<template>
  <div class="configurable-form">
    <vxe-form ref="formRef" v-bind="getFormBindValue" v-on="formEvents">
      <template #[item]="data" v-for="item in Object.keys($slots)">
        <slot :name="item" v-bind="data || {}"></slot>
      </template>
    </vxe-form>
  </div>
</template>

<script lang="ts" setup>
  import { reactive, onMounted, onUnmounted } from 'vue'
  import { VxeForm, VxeFormListeners, VxeFormInstance } from 'vxe-pc-ui'
  import { merge, isFunction } from 'xe-utils'
  import { addOnPrefix, isStrIncludes } from '@/utils'
  import { useEvents } from './useEvents'
  import { BasicFormProps, Props } from './types'
  // initRender
  import './renderer'

  const props = withDefaults(defineProps<Props>(), {
    searchBtns: () => ['search', 'reset'],
    clearable: true
  })

  defineEmits([])

  const attrs = useAttrs()
  const instance = getCurrentInstance()

  const { t } = useI18n()

  const defFormOptions = reactive<BasicFormProps>({
    titleColon: true,
    data: {},
    items: []
    // test
    // items: [
    //   {
    //     field: 'pageType',
    //     // span: 4,
    //     itemRender: {
    //       name: 'ElRadioGroup',
    //       options: [
    //         { label: t('custom.品种'), value: 'material' },
    //         { label: t('custom.机台'), value: 'equipment' }
    //       ],
    //       events: {
    //         change: (params, e) => {},
    //         VnodeMounted(params) {
    //           // 初始化触发时间更新
    //           formRef.value?.emitter.emit('field:pageType:change', params)
    //         }
    //       }
    //     }
    //   },
    //   {
    //     field: 'tsIdSelect',
    //     title: t('system.时间'),
    //     // span: 11,
    //     itemRender: {
    //       name: 'ShiftSchedulePicker',
    //       events: {
    //         confirm: (params) => {
    //           // 直接给loading 防止物料请求时间长
    //           // classifyGridOptions.loading = true
    //           // detailGridOptions.loading = true
    //           formRef.value?.emitter.emit('field:tsIdSelect:change', params)
    //         }
    //       }
    //     },
    //     dependencies: {
    //       pageType: async (params) => {
    //         const { banCiInfo, shiftOptions } = await getCurrentAndLastBanCi(props.gongXuId, {
    //           isGetLast: true
    //         })

    //         params.data[params.field] = banCiInfo

    //         // 触发物料更新
    //         formRef.value?.emitter.emit('field:tsIdSelect:change', params)

    //         // 返回相同结构的对象,更新当前item的渲染配置
    //         return {
    //           itemRender: {
    //             props: {
    //               shiftOptions
    //             }
    //           }
    //         }
    //       }
    //     }
    //   },
    //   {
    //     field: 'material',
    //     title: t('custom.物料'),
    //     // span: 6,
    //     itemRender: {
    //       name: 'SelectModal',
    //       props: {
    //         modalConfig: {
    //           title: t('system.列表选择', { name: t('custom.物料') })
    //         }
    //       }
    //     },
    //     dependencies: {
    //       tsIdSelect: async (params) => {
    //         if (params.data.pageType !== 'material') return
    //         const formData = params.data
    //         const { tsIdSelect } = formData
    //         const modalList = (
    //           await getgongYiBanCiGetWuLiaoList({
    //             craftNodeName: props.gongXuName,
    //             StartTsid: tsIdSelect.startTsId,
    //             EndTsid: tsIdSelect.endTsId
    //           })
    //         ).map((v) => ({ ...v, label: v.materialName, value: v.materialId }))
    //         // 全选
    //         Object.assign(params.data, { material: modalList.map((v) => v.value) })

    //         // 链式联动结束, 请求数据
    //         console.log('链式联动结束, 请求数据')
    //         handleSearch(params)
    //         // 返回相同结构的对象,更新当前item的渲染配置
    //         return {
    //           itemRender: {
    //             props: {
    //               modalConfig: {
    //                 options: modalList
    //               }
    //             }
    //           }
    //         }
    //       }
    //     }
    //   },
    //   {
    //     field: 'equipment',
    //     title: t('custom.机台'),
    //     // span: 6,
    //     visible: false,
    //     itemRender: {
    //       name: 'SelectModal',
    //       props: {
    //         modalConfig: {
    //           title: t('system.列表选择', { name: t('custom.机台') })
    //         }
    //       }
    //     },
    //     dependencies: {
    //       tsIdSelect: async (params) => {
    //         if (params.data.pageType !== 'equipment') return
    //         const modalList = await getJiTaiTheGongYi(props.gongXuId).then((res) => {
    //           return res.map((v) => ({ ...v, label: v.machineName, value: v.id }))
    //         })
    //         // 全选
    //         Object.assign(params.data, { equipment: modalList.map((v) => v.value) })
    //         // 链式联动结束, 请求数据
    //         console.log('链式联动结束, 请求数据')
    //         handleSearch(params)

    //         // 返回相同结构的对象,更新当前item的渲染配置
    //         return {
    //           itemRender: {
    //             props: {
    //               modalConfig: {
    //                 options: modalList
    //               }
    //             }
    //           }
    //         }
    //       }
    //     }
    //   },
    //   {
    //     // span: 2,
    //     itemRender: {
    //       name: 'ElButtons',
    //       children: [
    //         {
    //           type: 'primary',
    //           content: t('system.查询'),
    //           events: {
    //             click: (params) => {
    //               handleSearch(params)
    //             }
    //           }
    //         }
    //       ]
    //     }
    //   }
    // ]
  })

  const getFormBindValue = computed((): BasicFormProps => {
    const propsData: BasicFormProps = {
      ...attrs,
      ...defFormOptions,
      ...props.formOptions,
      // 挂载到表单的params属性上
      params: {
        ...(props.formOptions?.params || {}),
        emitter,
        updateFieldConfig,
        // 供渲染器使用
        executeEvent
      }
    }

    // 统一处理渲染器配置
    propsData.items.forEach((item) => {
      if (item.itemRender) {
        const { title } = item
        const { name } = item.itemRender
        if (isStrIncludes(name, 'input')) {
          item.itemRender.props = {
            placeholder: t('system.请输入', { name: title }),
            clearable: props.clearable,
            ...(item.itemRender.props || {})
          }
        } else if (isStrIncludes(name, 'select')) {
          item.itemRender.props = {
            placeholder: t('system.请选择', { name: title }),
            filterable: true,
            clearable: props.clearable,
            ...(item.itemRender.props || {})
          }
        } else if (isStrIncludes(name, 'DatePicker')) {
          item.itemRender.props = {
            placeholder: t('system.请选择', { name: title }),
            clearable: props.clearable,
            ...(item.itemRender.props || {})
          }
        } else if (isStrIncludes(name, 'ActionButtons')) {
          item.itemRender?.children?.forEach((btn) => {
            if (['search', 'reset'].includes(btn.name)) {
              btn.props = {
                ...(btn.props || {}),
                loading: props.searchLoading
              }
            }
          })
        }
      }
    })

    return propsData
  })

  const { emitter } = useEvents()

  const formEvents: VxeFormListeners = {
    // submit() {
    //   emits('submit', { ...getFormData.value })
    // },
    // reset() {
    //   emits('reset', { ...getFormData.value })
    // },
    ...props.formEvents
  }

  const formRef = ref<VxeFormInstance>()
  const getFormData = computed<Recordable>(() => getFormBindValue.value.data)

  // 生成事件名称（添加表单前缀，避免不同表单间的事件冲突）
  const getEventName = (event: string) => {
    // return props.formKey ? `${props.formKey}:${event}` : event
    return event
  }

  // 解析联动规则
  const parseDependencies = () => {
    getFormBindValue.value.items.forEach((item: BasicFormProps['items'][number]) => {
      const dependencies = item.dependencies
      const field = item.field

      if (field && dependencies) {
        Object.keys(dependencies).forEach((sourceField) => {
          const rule = dependencies[sourceField]
          // 注册事件监听
          const eventHandler = async (value: any) => {
            const _item = getItemByField(field)
            // 第一个参数是组件返回,第二个参数才是调用传参
            const newConfig = await rule(
              { $form: formRef.value!, item: _item!, field, data: getFormData.value },
              value
            )

            if (newConfig) {
              updateFieldConfig(field, newConfig)
            }
          }

          emitter.on(getEventName(`field:${sourceField}:change`), eventHandler)
          // 保存监听器引用，用于卸载时清理
          // if (!item._eventHandlers) {
          //   item._eventHandlers = []
          // }
          // item._eventHandlers.push({ event: `field:${field}:change`, handler: eventHandler })
        })
      }
      // emitter.on('submit', formEvents.submit)
    })
  }

  const getItems = () => {
    return formRef.value?.getItems()
  }

  const getItemByField = (field: string) => {
    return formRef.value?.getItemByField(field)
  }

  // 更新字段配置
  const updateFieldConfig = (field: string, newConfig: Recordable) => {
    const item = getFormBindValue.value.items.find((item) => item.field === field)
    if (item) {
      merge(item, newConfig)
    }
  }

  const executeEvent = (name: string, params: any, event: Event) => {
    // 获取所有props 包括未被定义与事件
    const allProps = instance?.vnode?.props || {}

    const eventName = addOnPrefix(name)

    if (allProps[eventName] && isFunction(allProps[eventName])) {
      allProps[eventName]({ ...params, $event: event })
    } else {
      console.warn(`事件"${name}"未注册或不是函数`)
    }
  }

  onMounted(() => {
    // 初始化联动规则
    parseDependencies()
  })

  onUnmounted(() => {
    emitter.all.clear()
    // props.schema.forEach((item) => {
    //   if (item._eventHandlers) {
    //     item._eventHandlers.forEach(({ event, handler }) => {
    //       emitter.off(getEventName(event), handler)
    //     })
    //     delete item._eventHandlers
    //   }
    // })
  })

  const expose = {
    /** 表单实例 */
    $form: formRef,
    /** emitter实例 */
    emitter,
    /** 获取事件名称 */
    // getEventName,
    /** 获取表单绑定值 */
    getFormData: () => getFormData.value,
    /** 更新字段配置 */
    updateFieldConfig,
    /** 获取所有表单项 */
    getItems,
    /** 获取指定表单项 */
    getItemByField,
    /** 重置 */
    reset: async () => await formRef.value?.reset(),
    /** 校验 */
    validate: async () => await formRef.value?.validate()
  }
  defineExpose(expose)
</script>
